package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.client.entity.ClientUser;
import cn.lg.soar.boot.client.service.ClientUserService;
import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.Process;
import cn.lg.soar.boot.fc.service.RentService;
import cn.lg.soar.boot.fc.service.RoomService;
import cn.lg.soar.boot.fc.service.TenancyRoomService;
import cn.lg.soar.common.algorithm.CryptoUtils;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.FileUtil;
import cn.lg.soar.common.util.data.RandomUtil;
import cn.lg.soar.database.query.SqueryWapper;
import cn.lg.soar.general.entity.FileMetadata;
import cn.lg.soar.general.manager.FileTemplateManager;
import cn.lg.soar.general.s3.FileTemplate;
import cn.lg.soar.general.service.IFileMetadataService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.boot.fc.mapper.ContractMapper;
import cn.lg.soar.boot.fc.service.ContractService;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 合同表
 * @author ZhuanZ（无密码）
 * @since 2025-02-18
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class ContractServiceImpl extends BaseServiceImpl<ContractMapper, Contract> implements ContractService {

    @Autowired
    private IFileMetadataService fileMetadataService;
    @Autowired
    private FileTemplateManager uploadTemplateManager;
    @Autowired
    private TenancyRoomService tenancyRoomService;
    @Autowired
    private RoomService roomService;
    @Autowired
    private RentService rentService;
    /** 客户端用户信息服务 */
    @Autowired private ClientUserService clientUserService;

    /**
     * 通过合同模板生成合同
     */
    @Transactional
    public HttpResult<Void> generateContract(Long tenancyId) {
        TenancyRoom tenancyRoom = tenancyRoomService.getById(tenancyId);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        Room room = roomService.getById(tenancyRoom.getRoomId());
        if (null == room){
            return HttpResult.fail("B0000", I18n.build("房间信息为空！"));
        }
        ClientUser user = clientUserService.getById(tenancyRoom.getUserId());
        if(user == null) {
            return HttpResult.fail("B0000", I18n.build("用户信息为空！"));
        }

        BigDecimal billAmount = new BigDecimal(0);
        Integer moonNum = 1;
        String payWay = "每月";
        if(room.getIsRent() == 1){
            HttpResult<Rent> resultRent = rentService.getById(room.getRentId());
            Rent rent = resultRent.getData();
            if (null == rent){
                return HttpResult.fail("B0000", I18n.build("租金信息为空！"));
            }
            if(rent.getRentcountway() == 3){
                moonNum = moonNum * 3;
                payWay = "每季";
            }else if(rent.getRentcountway() == 4){
                moonNum = moonNum * 6;
                payWay = "每半年";
            }else if(rent.getRentcountway() == 5){
                moonNum = moonNum * 12;
                payWay = "每年";
            }
            if(rent.getRentaccounting() == 2){
                billAmount = new BigDecimal(rent.getRentamount()).multiply(BigDecimal.valueOf(moonNum));
            }else if(rent.getRentaccounting() == 3){
                billAmount = new BigDecimal(rent.getRentamount()).multiply(BigDecimal.valueOf(Long.parseLong(room.getArea()))).multiply(BigDecimal.valueOf(moonNum));
            }

        }else{
            if(room.getPayWay() == 1){
                moonNum = moonNum * 3;
                payWay = "每季";
            }else if(room.getPayWay() == 2){
                moonNum = moonNum * 6;
                payWay = "每半年";
            }else if(room.getPayWay() == 3){
                moonNum = moonNum * 12;
                payWay = "每年";
            }
            billAmount = new BigDecimal(room.getRent()).multiply(BigDecimal.valueOf(moonNum));
        }
        tenancyRoom.setWaitPay(billAmount);
        tenancyRoom.setTenancyState(1);
        try {
            Map<String, Object> datas = new HashMap<String, Object>(); // 数据对象
            if(billAmount.compareTo(new BigDecimal(0)) == 0){
                datas.put("rent", "免租");
            }else{
                datas.put("rent", String.valueOf(billAmount));
            }
            datas.put("rentcountway", payWay);
//            FileMetadata metadata = fileMetadataService.getById(room.getContractTemplateId());
            FileMetadata metadata = fileMetadataService.getById(1891806496995389441L);
            AssertUtil.notNull(metadata, "链接无效");
            FileTemplate uploadTemplate = uploadTemplateManager.getTemplate(metadata.getStorageId());
            uploadTemplate.getInputStream(metadata.getBucketName(), metadata.filename());
            PdfReader reader = new PdfReader(uploadTemplate.getInputStream(metadata.getBucketName(), metadata.filename()));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            // 根据表单生成一个新的pdf
            PdfStamper stamper = new PdfStamper(reader, baos);
            // 获取pdf表单
            AcroFields formTexts = stamper.getAcroFields();
            // 设置字体(这里设置为系统字体，你也可以引入其他的字体)，不设置很可能，中文无法显示。
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            formTexts.addSubstitutionFont(baseFont);
            // 数据查询后，值的植入 强烈推荐键值方式，其他方式很容易混
            for (String key : datas.keySet()) {
                String value = (String) datas.get(key);
                formTexts.setField(key, value);
                formTexts.setFieldProperty(key, "textfont", baseFont, null); // 设置字体
            }
            System.out.println("Fields: " + formTexts.getFields().keySet());
            stamper.setFormFlattening(true); //这个必须设
            stamper.close();
            InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
            FileMetadata metadata1 = new FileMetadata();
            metadata1.setId(IdWorker.getId());
            metadata1.setOriginalName(metadata.getOriginalName());
            String md5 = CryptoUtils.md5Hex(baos.toByteArray());
            String code = FileUtil.toCode(md5, (long) baos.size());
            metadata1.setCode(code);
            metadata1.setStorageId(metadata.getStorageId());
            metadata1.setBucketName(metadata.getBucketName());
            metadata1.setSuffix(metadata.getSuffix());
            metadata1.setSize(baos.size());
            metadata1.setSecret(RandomUtil.getString(6, RandomUtil.SOURCE64));
            uploadTemplate.upload(metadata1.getBucketName(), metadata1.filename(), inputStream);
            AssertUtil.isTrue(fileMetadataService.save(metadata1), "创建失败");
            reader.close();
            inputStream.close();
            baos.close();

            String url = "fixed/"+metadata1.getSecret()+"/"+metadata1.getId()+"/"+user.getUserName()+"租房合同.pdf";
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            String contractCode = now.format(formatter) + tenancyId;
            Contract contract = new Contract();
            contract.setTemplateId(room.getContractTemplateId());
            contract.setTenancyId(tenancyId);
            contract.setCode(contractCode);
            contract.setVoucherUrl(url);
            AssertUtil.isTrue(super.save(contract), "创建失败");


            SqueryWapper squeryWapper = new SqueryWapper<>(Contract.class);
            QueryWrapper<Contract> wrapper = Wrappers.query();
            List<String> f = new ArrayList<>();
            f.add("code-eq~"+contractCode);
            squeryWapper.setWhere(f, wrapper);
            Contract contract1 = super.getOne(wrapper);
            if(contract1 != null){
                tenancyRoom.setContractId(contract1.getId());
            }
            tenancyRoom.setContractCode(contractCode);
            AssertUtil.isTrue(tenancyRoomService.updateById(tenancyRoom), "更新失败");
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail();
        }
        return HttpResult.success();
    }

    /**
     * 合同审核
     */
    @Transactional
    public HttpResult<Void> contractExamine(Long id,Integer state) {
        Contract contract = super.getById(id);
        if(contract == null){
            return HttpResult.fail("B0000", I18n.build("合同信息为空！"));
        }
        if(state == 1){
            tenancyRoomService.contractSign(contract.getTenancyId());
            contract.setState(2);
            contract.setSignTime(LocalDateTime.now());
            AssertUtil.isTrue(super.updateById(contract), "更新失败");
        }else if(state == 9){
            TenancyRoom tenancyRoom = tenancyRoomService.getById(id);
            if (null == tenancyRoom){
                return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
            }
            tenancyRoom.setTenancyState(1);
            AssertUtil.isTrue(tenancyRoomService.updateById(tenancyRoom), "更新失败");
            contract.setState(9);
            AssertUtil.isTrue(super.updateById(contract), "更新失败");
        }
        return HttpResult.success();
    }

}
